當我們在 template 訂閱一組資料,而需要對它做一些邏輯處理的時後。
.ts
export class TemplateComponent {
products$: Observable<any> = this.apiService.fetchProd();
constructor(public apiService: ApiService) {}
}
.html
<ng-container *ngIf="products$ | async as products;">
<ng-container *ngIf="products.length > 0; else empty">
<ng-container *ngFor="let item of products"> ...略 </ng-container>
</ng-container>
</ng-container>
<ng-template #empty> No Data </ng-template>
若像上述這樣的寫法,會造成重覆訂閱而增加 server 的負擔,所以在實作上,通常會避免這情況發生
將 html 寫法稍做修改
<ng-container *ngIf="(products$ | async)?.length > 0 as products; else empty">
<ng-container *ngFor="let item of products"> ...略 </ng-container>
</ng-container>
<ng-template #empty> No Data </ng-template>
將 products$ | async
定義為 products
。
這樣就只會被訂閱一次,而這麼做的好處也可以使程式碼更容易閱讀,
在 ts 檔裡加上 shareReplay
.ts
export class TemplateComponent {
products$: Observable<any> = this.apiService.fetchProd().pipe(
shareReplay()
);
constructor(public apiService: ApiService) {}
}
還有一點要注意的是,在 ng-container
裡,不能同時使用 ngIf
與 ngFor
否則會報錯唷唷唷~
明天會接續來說 ng-container 與 ng-template 這件事
附錄:RxJS Multicast 類 Operator (1) - multicast / publish / refCount / share / shareReplay